package com.android.justcook;

import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import camp.android.justcook.R;

/**
 * A very simple application to handle Voice Recognition intents and display the
 * results
 */
public class ReadStepActivity extends BaseActivity implements OnInitListener {
	private static final String TAG = "MainActivity";
	private static final int REQUEST_CODE = 1234;
	private TextToSpeech textToSpeech;
	private Button speakButton;
	private Handler handler;
	private Runnable restartRunnable;
	private AudioManager am;
	private int result;
	private RecipeGiver recipeGiver = null;
	private String currentStep = null;
	protected int recId;
	protected int catId;
	private boolean resetActivity = true;
	String REC_METHOD;

	// test recipe
	private String testRecipe = "We have a first step. Ofcourse we have a second stepp too. Sadly third step is the last one.";

	/**
	 * Called with the activity is first created.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {

		setContentView(R.layout.read_step);

		speakButton = (Button) findViewById(R.id.speakButton);

		textToSpeech = new TextToSpeech(this, this);
		this.resetActivity = true;

		// wordsList = (ListView) findViewById(R.id.list);

		// Creating audio manager for the muting of the sound
		am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

		// Disable button if no recognition service is present
		PackageManager pm = getPackageManager();
		List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(
				RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
		if (activities.size() == 0) {
			speakButton.setEnabled(false);
			speakButton.setText("Recognizer not present");
		}

		// workaround for the problem of the need to click okey button
		// with this handler the activity will refresh every 10 seconds
		// so there is no need for the user to click anything
		handler = new Handler();

		restartRunnable = new Runnable() {

			@Override
			public void run() {
				if (resetActivity)
					startActivity(new Intent(ReadStepActivity.this,
							ReadStepActivity.class)
							.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
							.putExtra("CATEGORY_ID", catId)
							.putExtra("rec_id", recId));
			}

		};

		ActionBar actionBar = getActionBar();
		actionBar.setDisplayHomeAsUpEnabled(true);

		recId = getIntent().getIntExtra("rec_id", 0);
		catId = getIntent().getIntExtra(MainActivity.EXTRA_MESSAGE, 0);

		REC_METHOD = MainActivity.MEALS_METHOD[catId][recId];
		int pic = MainActivity.MEALS_IMAGES[catId][recId];
		String recipe_name = MainActivity.MEALS[catId][recId];

		// setting up the RecipeGiver
		if (recipeGiver == null) {
			recipeGiver = new RecipeGiver(REC_METHOD);
		}

		actionBar.setTitle(recipe_name);

		ImageView img = (ImageView) findViewById(R.id.imageView1);
		img.setBackgroundResource(pic);

		TextView cover_text = (TextView) findViewById(R.id.cover_category);
		cover_text.setText(recipe_name);
		super.onCreate(savedInstanceState);
	}

	/**
	 * Handle the action of the button being clicked
	 */
	public void speakButtonClicked(View v) {
		textToSpeech.speak("Voice recognition started. Say go to begin", TextToSpeech.QUEUE_ADD, null);
		while(textToSpeech.isSpeaking()) {}
		startVoiceRecognitionActivity();
	}

	/**
	 * Fire an intent to start the voice recognition activity.
	 */
	private void startVoiceRecognitionActivity() {
		// muting the sounds
		am.setStreamMute(AudioManager.STREAM_SYSTEM, true);

		Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
		intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
				RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
		intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
				"Waiting for the next command.");
		startActivityForResult(intent, REQUEST_CODE);

		handler.removeCallbacks(restartRunnable);
		handler.postDelayed(restartRunnable, 6000);

		// unmuting the sound
		am.setStreamMute(AudioManager.STREAM_SYSTEM, true);
	}

	/**
	 * Handle the results from the voice recognition activity.
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
			Log.d(TAG, "found matches");
			// Populate the wordsList with the String values the recognition
			// engine thought it heard
			ArrayList<String> matches = data
					.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

			Log.d(TAG, "dump of matches: " + matches.toString());
			boolean recognizedWord = false;

			// checking for the word we need
			for (int i = 0; i < matches.size(); i++) {
				if (matches.get(i).equals("go")) {

					currentStep = recipeGiver.nextStep();

					if (currentStep.length() != 0) {
						result = speak(currentStep, textToSpeech);
					} else {
						result = speak("There are no more steps.", textToSpeech);
					}
					recognizedWord = true;

					// starting voice recognition
					Log.d(TAG, "1 " + result);
					startVoiceRecognitionActivity();
				} else if (matches.get(i).equals("back")) {

					currentStep = recipeGiver.backStep();

					if (currentStep.length() != 0) {
						result = speak(currentStep, textToSpeech);
					} else {
						result = speak("There are no more previous steps",
								textToSpeech);
					}
					recognizedWord = true;

					// starting voice recognition
					Log.d(TAG, "1 " + result);
					startVoiceRecognitionActivity();
				} else if (matches.get(i).equals("again")) {

					result = speak(currentStep, textToSpeech);
					recognizedWord = true;

					// starting voice recognition
					Log.d(TAG, "1 " + result);
					startVoiceRecognitionActivity();
				} else if (matches.get(i).equals("quit")) {

					result = speak("Exitting voice recognition", textToSpeech);
					
					if (recipeGiver.nextStep().length() == 0) {
						this.resetActivity = false;
						savePoints();
						finish();
						Intent intent = new Intent(this, FinishedActivity.class);
						intent.putExtra("rec_id", recId);
						intent.putExtra("CATEGORY_ID", catId);
						startActivity(intent);
					} else {
						this.resetActivity = false;
						finish();
						Intent intent = new Intent(this,
								ShowRecipeActivity.class);
						intent.putExtra(RecipesList.EXTRA_MESSAGEQ, recId);
						intent.putExtra("CATEGORY_ID", catId);
						startActivity(intent);
					}

					recognizedWord = true;
				}
			}

			if (!recognizedWord) {
				result = speak("Please try again!", textToSpeech);
				startVoiceRecognitionActivity();
			}
		} else {
			Intent restartIntent = new Intent(this, ReadStepActivity.class);
			startActivity(restartIntent);
			startVoiceRecognitionActivity();
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	public void onInit(int arg0) {
		// TODO Auto-generated method stub
		// Make sure the Text-To-Speech engine is fully loaded
		// It can be configured and used
		speakButton.setEnabled(true);
	}

	public int speak(String s, TextToSpeech tts) {
		int result = tts.speak(s, TextToSpeech.QUEUE_ADD, null);

		updateTextView(currentStep);
		while (tts.isSpeaking()) {}

		return result;
	}

	public void updateTextView(String text) {
		TextView textView = (TextView) findViewById(R.id.step_text);
		textView.setText(recipeGiver.getCurrentStep() + ". " + text + ".");

		Button btn = (Button) findViewById(R.id.speakButton);
		btn.setVisibility(View.GONE);

		View img = findViewById(R.id.voice_layout);
		img.setVisibility(View.GONE);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:

			Intent intent = new Intent(this, ShowRecipeActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			intent.putExtra("rec_id", recId);
			intent.putExtra("CATEGORY_ID", catId);
			startActivity(intent);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	public void savePoints() {
		int points = Integer.valueOf(MainActivity.MEALS_POINTS[catId][recId]);
		int newPoints;

		SharedPreferences sp = getSharedPreferences(PREFS_NAME, 0);
		newPoints = points + sp.getInt(POINTS, 0);

		SharedPreferences.Editor editor = sp.edit();
		editor.putInt(POINTS, newPoints);
		editor.commit();
	}
}